package com.ruicar.afs.cloud.apply.pre.loan.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruicar.afs.cloud.apply.common.dto.ProductInfoDTO;
import com.ruicar.afs.cloud.apply.common.entity.ApplyCarDetails;
import com.ruicar.afs.cloud.apply.common.entity.ApplyChannelInfo;
import com.ruicar.afs.cloud.apply.common.entity.ApplyCustPersonalDetail;
import com.ruicar.afs.cloud.apply.common.entity.ApplyOrderInfo;
import com.ruicar.afs.cloud.apply.common.feign.Apply2ProductFeign;
import com.ruicar.afs.cloud.apply.common.utils.ApplyConfig;
import com.ruicar.afs.cloud.apply.common.utils.ApplyConstants;
import com.ruicar.afs.cloud.apply.common.utils.ApplyUtils;
import com.ruicar.afs.cloud.apply.pre.loan.condition.CarInfoCondition;
import com.ruicar.afs.cloud.apply.pre.loan.service.*;
import com.ruicar.afs.cloud.bizcommon.algorithm.enums.CalculateType;
import com.ruicar.afs.cloud.bizcommon.algorithm.service.AfsAlgorithmService;
import com.ruicar.afs.cloud.bizcommon.algorithm.service.FinanceCalculatorService;
import com.ruicar.afs.cloud.bizcommon.business.bean.AfsRepaymentInfo;
import com.ruicar.afs.cloud.bizcommon.business.dto.CalculatorDTO;
import com.ruicar.afs.cloud.bizcommon.business.dto.CalculatorListDTO;
import com.ruicar.afs.cloud.bizcommon.business.entity.FinCostDetails;
import com.ruicar.afs.cloud.bizcommon.business.entity.FinDiscountDetails;
import com.ruicar.afs.cloud.bizcommon.business.entity.FinFinancingItems;
import com.ruicar.afs.cloud.bizcommon.business.entity.FinRentAdjustDetails;
import com.ruicar.afs.cloud.bizcommon.business.mapper.ApplyCostDetailsMapper;
import com.ruicar.afs.cloud.bizcommon.business.service.ApplyCostDetailsService;
import com.ruicar.afs.cloud.bizcommon.business.service.ApplyDiscountDetailsService;
import com.ruicar.afs.cloud.bizcommon.business.service.ApplyFinancingItemsService;
import com.ruicar.afs.cloud.bizcommon.business.service.ApplyRentAdjustDetailsService;
import com.ruicar.afs.cloud.bizcommon.business.vo.RepaymentPlanVO;
import com.ruicar.afs.cloud.common.core.constant.CommonConstants;
import com.ruicar.afs.cloud.common.core.security.util.SecurityUtils;
import com.ruicar.afs.cloud.common.core.util.IResponse;
import com.ruicar.afs.cloud.parameter.commom.enums.CarNature;
import com.ruicar.afs.cloud.parameter.commom.enums.CostType;
import com.ruicar.afs.cloud.parameter.commom.enums.WhetherEnum;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @description: 产品服务类
 * @author: sijun.yu
 * @date: 2020/7/15 15:20
 */
@Slf4j
@Service
@AllArgsConstructor
public class ApplyProductServiceImpl extends ServiceImpl<ApplyCostDetailsMapper, FinCostDetails> implements ApplyProductService {

    private ApplyConfig config;
    private Apply2ProductFeign productFeign;

    private FinanceCalculatorService financeCalculatorService;
    private AfsAlgorithmService afsAlgorithmService;

    private ApplyOrderInfoService orderInfoService;
    private ApplyCarDetailsService carDetailsService;
    private ApplyChannelInfoService channelInfoService;
    private ApplyCostDetailsService costDetailsService;
    private ApplyFinancingItemsService financingItemsService;
    private ApplyCustPersonalService custPersonalService;
    private ApplyRentAdjustDetailsService rentAdjustDetailsService;
    private ApplyDiscountDetailsService discountDetailsService;

    /**
     * 获取产品请求头
     *
     * @return
     */
    public Map makeProductHeader() {
        Map<String, String> headers = new HashMap<>();
        headers.put("clientId", config.getProductClientId());
        headers.put("clientSecret", config.getProductClientSecret());
        return headers;
    }

    /**
     * 查询产品列表
     *
     * @param condition
     * @return
     */
    @Override
    public JSONObject queryProductSelectList(CalculatorDTO condition) {

        String applyNo = condition.getApplyNo();
        ProductInfoDTO dto = new ProductInfoDTO();
        dto.setPageNo(condition.getPageNo());
        dto.setPageSize(condition.getPageSize());
        if(StringUtil.isNotBlank(condition.getProductName())){
            dto.setProductName(condition.getProductName());
        }
        // 获取订单信息
        ApplyOrderInfo orderInfo = orderInfoService.getOrderInfoByApplyNo(applyNo);
        if (orderInfo != null) {
            dto.setAtomInfo(orderInfo);
        }
        // 获取车辆信息
        ApplyCarDetails carDetails = carDetailsService.getCarDetailsByApplyNo(applyNo);
        if (carDetails != null) {
            dto.setCarInfo(carDetails);
        }
        // 渠道信息
        ApplyChannelInfo channelInfo = channelInfoService.getChannelInfoByApplyNo(applyNo);
        if (channelInfo != null) {
            dto.setChannelInfo(channelInfo);
        }
        log.info(applyNo+"获取产品投放参数："+JSONObject.toJSON(dto).toString());
        return productFeign.queryProductSelectList(dto, makeProductHeader());
    }

    /**
     * 查询产品详情
     *
     * @param condition
     * @return
     */
    @Override
    public IResponse queryProductDetails(CalculatorDTO condition) {

        String applyNo = condition.getApplyNo();
        ProductInfoDTO dto = new ProductInfoDTO();
        dto.setId(condition.getId());
        // 原子信息
        ApplyOrderInfo orderInfo = orderInfoService.getOrderInfoByApplyNo(applyNo);
        if (orderInfo != null) {
            dto.setAtomInfo(orderInfo);
        }
        // 渠道信息
        ApplyChannelInfo channelInfo = channelInfoService.getChannelInfoByApplyNo(applyNo);
        if (channelInfo != null) {
            dto.setChannelInfo(channelInfo);
        }
        // 车辆信息
        ApplyCarDetails carDetails = carDetailsService.getCarDetailsByApplyNo(applyNo);
        if (carDetails != null) {
            dto.setCarInfo(carDetails);
        }
        log.info(applyNo+"获取产品详情参数："+JSONObject.toJSON(dto).toString());
        IResponse iResponse = productFeign.queryProductDetails(dto, this.makeProductHeader());
        return iResponse;
    }

    /**
     * 获取产品利率
     *
     * @param condition
     * @return
     */
    @Override
    public IResponse getProductRate(CalculatorDTO condition) {

        String applyNo = condition.getApplyNo();
        ProductInfoDTO dto = new ProductInfoDTO();
        dto.setId(condition.getId());
        // 原子信息
        ApplyOrderInfo orderInfo = orderInfoService.getOrderInfoByApplyNo(applyNo);
        if (orderInfo != null) {
            dto.setAtomInfo(orderInfo);
        }
        // 车辆信息
        ApplyCarDetails carDetails = carDetailsService.getCarDetailsByApplyNo(applyNo);
        if (carDetails != null) {
            dto.setCarInfo(carDetails);
        }
        // 渠道信息
        ApplyChannelInfo channelInfo = channelInfoService.getChannelInfoByApplyNo(applyNo);
        if (channelInfo != null) {
            dto.setChannelInfo(channelInfo);
        }
        // 利率信息
        if (CostType.CARAMT.getIndex().equals(condition.getCostType())) {
            FinCostDetails mainProductInfo = new FinCostDetails();
            mainProductInfo.setProductId(condition.getId().toString());
            mainProductInfo.setLoanTerm(condition.getLoanTerm());
            dto.setMainProductInfo(mainProductInfo);
        } else if (CostType.AFFIXAMT.getIndex().equals(condition.getCostType())) {
            FinCostDetails addProductInfo = new FinCostDetails();
            addProductInfo.setLoanTerm(condition.getLoanTerm());
            addProductInfo.setProductId(condition.getAddId().toString());
            dto.setAddProductInfo(addProductInfo);
        }
        // 获取产品利率
        log.info(applyNo+"获取产品利率参数："+JSONObject.toJSON(dto).toString());
        IResponse<JSONObject> iResponse = productFeign.getCustomerRate(dto, this.makeProductHeader());
        if(!CommonConstants.SUCCESS.equals(iResponse.getCode())){
            return iResponse;
        }
        // 车辆
        if (CostType.CARAMT.getIndex().equals(condition.getCostType())) {
            if(iResponse.getData().getJSONObject("main")==null){
                return IResponse.fail("客户利率为空，请输入正确产品期数");
            }
        }else{
            if(iResponse.getData().getJSONObject("son")==null){
                return IResponse.fail("客户利率为空，请输入正确产品期数");
            }
        }
        return iResponse;
    }

    /**
     * 产品校验
     *
     * @return
     */
    @Override
    public IResponse checkProductInfo(CalculatorListDTO costInfo) {

        ProductInfoDTO dto = new ProductInfoDTO();
        dto.setTotalContractAmt(costInfo.getTotalContractAmt());
        dto.setTotalLoanAmt(costInfo.getTotalLoanAmt());
        dto.setTotalFirstAmt(costInfo.getTotalFirstAmt());
        dto.setTotalDiscountAmt(costInfo.getTotalDiscountAmt());
        dto.setTotalInterest(costInfo.getTotalInterest());
        dto.setTotalRent(costInfo.getTotalRent());
        List<CalculatorDTO> list = costInfo.getCostList();
        for (CalculatorDTO productCondition : list) {
            // 车款费用信息
            if (CostType.CARAMT.getIndex().equals(productCondition.getCostType())) {
                FinCostDetails mainProductInfo = new FinCostDetails();
                BeanUtils.copyProperties(productCondition, mainProductInfo);
                dto.setMainProductInfo(mainProductInfo);
                List<FinFinancingItems> financingItemsList = new ArrayList<FinFinancingItems>();
                List<FinFinancingItems> itemsList = productCondition.getItemsList();
                if (itemsList != null && itemsList.size() > 0) {
                    //addContractAmt = itemsList.stream().map(FinFinancingItems::getFinanceItemAmt).reduce(BigDecimal.ZERO,BigDecimal::add);
                    for (FinFinancingItems itemsCondition : itemsList) {
                        List<FinFinancingItems> sonList = itemsCondition.getSonList();
                        if (sonList != null && sonList.size() > 0) {
                            financingItemsList.addAll(sonList);
                        }
                    }
                    financingItemsList.addAll(itemsList);
                }
                dto.setExtrasInfoList(financingItemsList);
                // 0-主产品和子产品为同一个
                if (WhetherEnum.No.getIndex().equals(productCondition.getIsSubProduct())) {
                    FinCostDetails addProductInfo = new FinCostDetails();
                    addProductInfo.setContractAmt(productCondition.getAddAmt());
                    dto.setAddProductInfo(addProductInfo);
                }
            }
            // 附加贷费用信息
            else if (CostType.AFFIXAMT.getIndex().equals(productCondition.getCostType())) {
                List<FinFinancingItems> financingItemsList = new ArrayList<FinFinancingItems>();
                List<FinFinancingItems> itemsList = productCondition.getItemsList();
                if (itemsList != null && itemsList.size() > 0) {
                    financingItemsList.addAll(itemsList);
                    for (FinFinancingItems itemsCondition : itemsList) {
                        List<FinFinancingItems> sonList = itemsCondition.getSonList();
                        if (sonList != null && sonList.size() > 0) {
                            financingItemsList.addAll(sonList);
                        }
                    }
                }
                FinCostDetails addProductInfo = new FinCostDetails();
                BeanUtils.copyProperties(productCondition, addProductInfo);
                dto.setAddProductInfo(addProductInfo);
                dto.setExtrasInfoList(financingItemsList);
            }
        }
        // 车辆信息
        ApplyCarDetails carDetails = carDetailsService.getCarDetailsByApplyNo(costInfo.getApplyNo());
        if (carDetails != null) {
            dto.setCarInfo(carDetails);
        }
        log.info(costInfo.getApplyNo()+"获取产品校验参数："+JSONObject.toJSON(dto).toString());
        IResponse iResponse = productFeign.checkProductInfo(dto, this.makeProductHeader());
        return iResponse;
    }

    /**
     * 风控准入校验
     *
     * @param applyNo
     * @return
     */
    @Override
    public IResponse chenkRiskInfo(String applyNo) {

        ProductInfoDTO dto = new ProductInfoDTO();
        // 渠道信息
        ApplyChannelInfo channelInfo = channelInfoService.getChannelInfoByApplyNo(applyNo);
        if (channelInfo != null) {
            dto.setChannelInfo(channelInfo);
        }
        // 车辆信息
        ApplyCarDetails carDetails = carDetailsService.getCarDetailsByApplyNo(applyNo);
        if (carDetails != null) {
            dto.setCarInfo(carDetails);
        }
        // 车款费用信息
        FinCostDetails carCostInfo = costDetailsService.getApplyCostDetails(applyNo, CostType.CARAMT.getIndex());
        if (carCostInfo != null) {
            dto.setMainProductInfo(carCostInfo);
        }
        // 附加贷费用信息
        FinCostDetails addCostInfo = costDetailsService.getApplyCostDetails(applyNo, CostType.AFFIXAMT.getIndex());
        if (addCostInfo != null) {
            dto.setAddProductInfo(addCostInfo);
        }
        // 融资项目
        List<FinFinancingItems> financingItemsList = financingItemsService.getApplyFinancingItemsList(applyNo);
        if (financingItemsList != null && financingItemsList.size() > 0) {
            dto.setExtrasInfoList(financingItemsList);
        }
        // 原子信息
        ApplyOrderInfo orderInfo = orderInfoService.getOrderInfoByApplyNo(applyNo);
        if (orderInfo != null) {
            dto.setAtomInfo(orderInfo);
            if(ApplyConstants.APPLY_STATUS_DRAFT.equals(orderInfo.getApplyStatus())){
                dto.setHasProductValid("yes");
            }
        }
        // 主借人客户明细
        ApplyCustPersonalDetail custPersonalDetail = custPersonalService.getPersonalDetailForMain(applyNo, ApplyConstants.PRINCIPAL_BORROWER);
        if (custPersonalDetail != null) {
            dto.setCustPersonalInfo(custPersonalDetail);
        }
        // 共借人明细信息
        ApplyCustPersonalDetail custInfoCoBorrower = custPersonalService.getPersonalDetailForMain(applyNo, ApplyConstants.COMMON_BORROWER);
        if (custInfoCoBorrower != null){
            dto.setCustInfoCoBorrower(custInfoCoBorrower);
            dto.setHasCommonBorrower("yes");
        }
        // 保证人客户明细
        ApplyCustPersonalDetail custInfoGuarantee = custPersonalService.getPersonalDetailForMain(applyNo, ApplyConstants.GUARANTOR);
        if (custInfoGuarantee != null){
            dto.setCustInfoGuarantee(custInfoGuarantee);
            dto.setHasBail("yes");
        }
        log.info(applyNo+"风控准入参数："+JSONObject.toJSON(dto).toString());
        IResponse iResponse = productFeign.chenkRiskInfo(dto, this.makeProductHeader());
        return iResponse;
    }

    /**
     * 调用计算器，生成单个还款计划表
     *
     * @param condition
     * @return
     */
    @Override
    public IResponse getArbitraryRepaymentPlan(CalculatorDTO condition) {

        // add by sijun.yu 2020-9-10 任意贷逻辑控制
        String algorithmType = condition.getAlgorithmType();
        if(CalculateType.arbitraryloan.getValue().equals(algorithmType)){
            ProductInfoDTO dto = new ProductInfoDTO();
            dto.setId(Long.valueOf(condition.getProductId()));
            IResponse<JSONObject> productJson = productFeign.queryProductDetails(dto, this.makeProductHeader());
            financeCalculatorService.getProductParameter(productJson.getData(),condition,null);
            // 租金列表判断
            List<FinRentAdjustDetails> rentList = condition.getRentList();
            Assert.isTrue(rentList!=null && rentList.size()>0,"任意贷产品必须调整租金才能计算");
            // 调整后月供
            double minRent = rentList.stream().mapToDouble(x -> x.getRent().doubleValue()).min().getAsDouble();
            Assert.isTrue(minRent>=condition.getAdjustedMonthlyPayments().doubleValue(),"调整后月供不能低于"+condition.getAdjustedMonthlyPayments());
            // 任意贷期数设定(n)
            Integer maxPeriod = condition.getSetAnyNumberCredits();
            // 前N期还款总额
            List<AfsRepaymentInfo> repaymentList = condition.getRepaymentList();
            Assert.isTrue(repaymentList!=null && repaymentList.size()>0,"还款计划表不能为空");
            double totalRent = repaymentList.subList(0,maxPeriod).stream().mapToDouble(x -> x.getYueGong().doubleValue()).sum();
            Assert.isTrue(totalRent>=condition.getTotalAmountInstalments().doubleValue(),"前"+maxPeriod+"期还款总额不能低于"+condition.getTotalAmountInstalments());
        }

        IResponse iResponse = financeCalculatorService.getSingleRepaymentPlan(condition);
        return iResponse;
    }

    /**
     * 调用计算器，生成2个还款计划表
     *
     * @param list
     * @return
     */
    @Override
    public IResponse financeCalculation(List<CalculatorDTO> list) {

        IResponse iResponse = financeCalculatorService.getMultipleRepaymentPlan(list);
        return iResponse;
    }

    /**
     * 通过贴息金额获取客户利率
     *
     * @param condition
     * @return
     */
    @Override
    public IResponse getCustRate(CalculatorDTO condition) {

        IResponse iResponse = afsAlgorithmService.getCustomerRate(condition);
        BigDecimal customerRate = (BigDecimal)iResponse.getData();
        Assert.isTrue(customerRate.compareTo(BigDecimal.ZERO)>=0,"贴息金额输入过大，请重新输入");
        return iResponse;
    }

    /**
     * 搜索附加项目名称
     * @param condition
     * @return
     */
    public IResponse queryExtrasInfoSonList(ProductInfoDTO condition){

        return productFeign.queryExtrasInfoSonList(condition,this.makeProductHeader());
    }

    /**
     * 保存融资列表信息
     *
     * @param applyNo
     * @param inList
     * @return
     */
    @Override
    public List<FinCostDetails> saveCostList(String applyNo, List<CalculatorDTO> inList) {

        String carAlgorithmType = "";// 车款的算法类型
        String channelName = SecurityUtils.getUser().getUserExtInfo().getJSONObject("channelInfo").getString("channelFullName");
        ApplyCarDetails carDetails = carDetailsService.getCarDetailsByApplyNo(applyNo);
        ApplyOrderInfo orderInfo = orderInfoService.getOrderInfoByApplyNo(applyNo);
        // 保存融资列表信息
        for (CalculatorDTO condition : inList) {
            // 赋值CarId
            if (carDetails != null) {
                if (CostType.CARAMT.getIndex().equals(condition.getCostType())) {
                    carAlgorithmType = condition.getAlgorithmType();
                    // 更新销售价格
                    carDetails.setSalePrice(condition.getContractAmt());
                    if(ApplyConstants.BUSINESS_TYPE_OLD_CAR.equals(orderInfo.getBusinessType())){
                        carDetails.setSecondSalePrice(condition.getContractAmt());
                    }
                    Assert.isTrue(carDetails.getGuidePrice().compareTo(carDetails.getSalePrice()) >= 0, "车辆价格不能超过指导价格");
                    carDetailsService.updateById(carDetails);
                    // 更新产品信息
                    orderInfo.setProductId(condition.getProductId());
                    orderInfo.setProductName(condition.getProductName());
                    orderInfoService.updateById(orderInfo);
                    if(CalculateType.arbitraryloan.getValue().equals(carAlgorithmType)){
                        List<FinRentAdjustDetails> rentList = condition.getRentList();
                        Assert.isTrue(rentList!=null && rentList.size()>0,"任意贷产品必须调整租金才能保存");
                    }
                    // add by sijun.yu 2020-10-12 同一个子产品控制addAmt不能为空
                    if(WhetherEnum.No.getIndex().equals(condition.getIsSubProduct())){
                        Assert.isTrue(condition.getAddAmt()!=null,"同一个产品时，附加金额不允许为空");
                    }
                }
            }
            // 贴息明细
            List<FinDiscountDetails> discountList = condition.getDiscountList();
            if(discountList!=null && discountList.size()>0){
                for(FinDiscountDetails discountDetails:discountList){
                    if("0".equals(discountDetails.getDiscountId())){// 0-厂商
                        discountDetails.setDiscountParty(ApplyUtils.dicData(discountDetails.getDiscountParty(), "subsidyNameType"));
                    }else if("1".equals(discountDetails.getDiscountId())){// 1-合作商
                        discountDetails.setDiscountParty(channelName);
                    }else if("2".equals(discountDetails.getDiscountId())){// 2-车商
                        discountDetails.setDiscountParty(orderInfo.getDealerName());
                    }
                }
            }
        }
        if(!CalculateType.arbitraryloan.getValue().equals(carAlgorithmType)){
            List<FinRentAdjustDetails> rentList = rentAdjustDetailsService.getRentAdjustDetails(applyNo);
            if(rentList!=null && rentList.size()>0){
                for(FinRentAdjustDetails rentAdjustDetails:rentList){
                    rentAdjustDetailsService.removeById(rentAdjustDetails.getId());
                }
            }
        }
        // 保存金融产品数据
        List<FinCostDetails> resultList = costDetailsService.saveCostDetailsList(applyNo, carDetails.getId(), inList);
        return resultList;
    }

    /**
     * 更新融资列表信息
     *
     * @param applyNo
     * @param inList
     */
    @Override
    public List<FinCostDetails> updateCostList(String applyNo, List<CalculatorDTO> inList) {

        String carAlgorithmType = "";// 车款的算法类型
        String reappearFlag = WhetherEnum.No.getIndex();
        String channelName = SecurityUtils.getUser().getUserExtInfo().getJSONObject("channelInfo").getString("channelFullName");
        ApplyOrderInfo orderInfo = orderInfoService.getOrderInfoByApplyNo(applyNo);
        ApplyCarDetails carDetails = carDetailsService.getCarDetailsByApplyNo(applyNo);
        FinCostDetails carCostInfo = costDetailsService.getApplyCostDetails(applyNo, CostType.CARAMT.getIndex());
        for (CalculatorDTO condition : inList) {
            if (CostType.CARAMT.getIndex().equals(condition.getCostType())) {
                // 更新销售价格
                carDetails.setSalePrice(condition.getContractAmt());
                if(ApplyConstants.BUSINESS_TYPE_OLD_CAR.equals(orderInfo.getBusinessType())){
                    carDetails.setSecondSalePrice(condition.getContractAmt());
                }
                Assert.isTrue(carDetails.getGuidePrice().compareTo(carDetails.getSalePrice()) >= 0, "车辆价格不能超过指导价格");
                carDetailsService.updateById(carDetails);
                // 更新产品信息
                if(!orderInfo.getProductId().equals(condition.getProductId())){// 金融产品
                    reappearFlag = WhetherEnum.YES.getIndex();
                }
                if(carCostInfo!=null){
                    // 贷款金额
                    if(carCostInfo.getLoanAmt().compareTo(condition.getLoanAmt())!=0){
                        reappearFlag = WhetherEnum.YES.getIndex();
                    }
                    // 期限
                    if(carCostInfo.getLoanTerm()!=condition.getLoanTerm()){
                        reappearFlag = WhetherEnum.YES.getIndex();
                    }
                }
                orderInfo.setProductId(condition.getProductId());
                orderInfo.setProductName(condition.getProductName());
                orderInfo.setReappearFlag(reappearFlag);
                orderInfoService.updateById(orderInfo);

                carAlgorithmType = condition.getAlgorithmType();
                if(CalculateType.arbitraryloan.getValue().equals(carAlgorithmType)){
                    List<FinRentAdjustDetails> rentList = condition.getRentList();
                    Assert.isTrue(rentList!=null && rentList.size()>0,"任意贷产品必须调整租金才能保存");
                }
                // add by sijun.yu 2020-10-12 同一个子产品控制addAmt不能为空
                if(WhetherEnum.No.getIndex().equals(condition.getIsSubProduct())){
                    Assert.isTrue(condition.getAddAmt()!=null,"同一个产品时，附加金额不允许为空");
                }
            }
            // 贴息明细
            List<FinDiscountDetails> discountList = condition.getDiscountList();
            if(discountList!=null && discountList.size()>0){
                for(FinDiscountDetails discountDetails:discountList){
                    if("0".equals(discountDetails.getDiscountId())){// 0-厂商
                        discountDetails.setDiscountParty(ApplyUtils.dicData(discountDetails.getDiscountParty(), "subsidyNameType"));
                    }else if("1".equals(discountDetails.getDiscountId())){// 1-合作商
                        discountDetails.setDiscountParty(channelName);
                    }else if("2".equals(discountDetails.getDiscountId())){// 2-车商
                        discountDetails.setDiscountParty(orderInfo.getDealerName());
                    }
                }
            }
        }
        if(!CalculateType.arbitraryloan.getValue().equals(carAlgorithmType)){
            List<FinRentAdjustDetails> rentList = rentAdjustDetailsService.getRentAdjustDetails(applyNo);
            if(rentList!=null && rentList.size()>0){
                for(FinRentAdjustDetails rentAdjustDetails:rentList){
                    rentAdjustDetailsService.removeById(rentAdjustDetails.getId());
                }
            }
        }
        // 更新金融产品数据
        List<FinCostDetails> resultList = costDetailsService.updateCostDetailsList(applyNo, carDetails.getId(), inList);
        return resultList;
    }

    /**
     * 修改车价重新调用计算器
     * @param applyNo
     * @param carDetails
     */
    @Override
    public void updateFinanceInfoForSalePrice(String applyNo, ApplyCarDetails carDetails, CarInfoCondition condition){

        FinCostDetails finCostDetails = costDetailsService.getApplyCostDetails(applyNo,CostType.CARAMT.getIndex());
        // 只修改价格，调用计算器重新计算
        if(carDetails.getStyleName().equals(condition.getStyleName()) && finCostDetails!=null){
            BigDecimal salePrice = BigDecimal.ZERO;
            if(CarNature.NEW_CAR.getIndex().equals(condition.getCarNature()) || CarNature.PLATE_CAR.getIndex().equals(condition.getCarNature())){
                Assert.isTrue(condition.getSalePrice()!=null,"车辆价格不能为空");
                salePrice = condition.getSalePrice();
            }else{
                Assert.isTrue(condition.getSecondSalePrice()!=null,"二手车销售价格不能为空");
                salePrice = condition.getSecondSalePrice();
            }
            if(finCostDetails.getContractAmt().compareTo(salePrice)!=0){
                // 获取产品详情
                BigDecimal hundred = new BigDecimal("100");
                ProductInfoDTO dto = new ProductInfoDTO();
                ApplyOrderInfo orderInfo = orderInfoService.getOrderInfoByApplyNo(applyNo);
                dto.setId(Long.valueOf(orderInfo.getProductId()));
                IResponse<JSONObject> productJson = productFeign.queryProductDetails(dto, this.makeProductHeader());

                // 获取算法参数
                CalculatorDTO carProuctDto = new CalculatorDTO();
                finCostDetails.setContractAmt(salePrice);
                BigDecimal downPayAmt = BigDecimal.ZERO;
                BigDecimal tailPayAmt = BigDecimal.ZERO;
                BigDecimal loanAmt = BigDecimal.ZERO;
                if(WhetherEnum.No.getIndex().equals(finCostDetails.getIsSubProduct()) && finCostDetails.getAddAmt()!=null && finCostDetails.getAddAmt().compareTo(BigDecimal.ZERO)>0){
                    downPayAmt = salePrice.add(finCostDetails.getAddAmt()).multiply(finCostDetails.getDownPayScale()).divide(hundred,2,BigDecimal.ROUND_HALF_DOWN);
                    if(finCostDetails.getTailPayScale()!=null){
                        tailPayAmt = salePrice.add(finCostDetails.getAddAmt()).multiply(finCostDetails.getTailPayScale()).divide(hundred,2,BigDecimal.ROUND_HALF_DOWN);
                    }
                    loanAmt = salePrice.add(finCostDetails.getAddAmt()).subtract(downPayAmt);
                }else{
                    downPayAmt = salePrice.multiply(finCostDetails.getDownPayScale()).divide(hundred,2,BigDecimal.ROUND_HALF_DOWN);
                    if(finCostDetails.getTailPayScale()!=null){
                        tailPayAmt = salePrice.multiply(finCostDetails.getTailPayScale()).divide(hundred,2,BigDecimal.ROUND_HALF_DOWN);
                    }
                    loanAmt = salePrice.subtract(downPayAmt);
                }
                // 修改贷款金额，涉及到重签标识
                if(loanAmt.compareTo(finCostDetails.getLoanAmt())!=0){
                    orderInfo.setReappearFlag(WhetherEnum.YES.getIndex());
                    orderInfoService.updateById(orderInfo);
                }
                finCostDetails.setDownPayAmt(downPayAmt);
                finCostDetails.setTailPayAmt(tailPayAmt);
                finCostDetails.setLoanAmt(loanAmt);
                BeanUtils.copyProperties(finCostDetails,carProuctDto);
                List<FinRentAdjustDetails> rentList = rentAdjustDetailsService.getRentAdjustDetails(applyNo);
                if(rentList!=null && rentList.size()>0){
                    carProuctDto.setRentList(rentList);
                }

                CalculatorDTO addProductDto = null;
                FinCostDetails addCostDetails = costDetailsService.getApplyCostDetails(applyNo,CostType.AFFIXAMT.getIndex());
                if(addCostDetails != null){
                    addProductDto = new CalculatorDTO();
                    BeanUtils.copyProperties(addCostDetails,addProductDto);
                }
                // 调用计算器
                List<CalculatorDTO> inList = financeCalculatorService.getProductParameter(productJson.getData(),carProuctDto,addProductDto);
                IResponse<RepaymentPlanVO> repaymentPlanVO = this.financeCalculation(inList);
                costDetailsService.updateCostDetailsForSalePrice(applyNo, carDetails.getId(), repaymentPlanVO.getData().getCostList());
            }
        }
        // modify by sijun.yu 换车之后更新金融产品【bug编号3560】
        else{
            List<FinCostDetails> costList = costDetailsService.getCostDetailsList(applyNo);
            if(CollectionUtil.isNotEmpty(costList)){
                costDetailsService.removeByIds(costList.stream().map(costDetails -> Convert.toStr(costDetails.getId())).collect(Collectors.toList()));
            }
            List<FinFinancingItems> itmeList = financingItemsService.getApplyFinancingItemsList(applyNo);
            if(CollectionUtil.isNotEmpty(itmeList)){
                financingItemsService.removeByIds(itmeList.stream().map(financingItems -> Convert.toStr(financingItems.getId())).collect(Collectors.toList()));
            }
            List<FinRentAdjustDetails> rentList = rentAdjustDetailsService.getRentAdjustDetails(applyNo);
            if(CollectionUtil.isNotEmpty(rentList)){
                rentAdjustDetailsService.removeByIds(rentList.stream().map(finRentAdjustDetails -> Convert.toStr(finRentAdjustDetails.getId())).collect(Collectors.toList()));
            }
            List<FinDiscountDetails> discountList = discountDetailsService.getDiscountDetailsList(applyNo);
            if(CollectionUtil.isNotEmpty(discountList)){
                discountDetailsService.removeByIds(discountList.stream().map(finDiscountDetails -> Convert.toStr(finDiscountDetails.getId())).collect(Collectors.toList()));
            }
        }
    }

    /**
     * 金融产品-融资计算器-For-App
     * @param condition
     * @return
     */
    @Override
    public IResponse financeProductCalculation(CalculatorListDTO condition){

        String productId = condition.getProductId();
        Assert.isTrue(productId != null,"金融产品不能为空");

        // 获取产品详情
        ProductInfoDTO dto = new ProductInfoDTO();
        dto.setId(Long.valueOf(productId));
        IResponse<JSONObject> productJson = productFeign.queryProductDetails(dto, this.makeProductHeader());

        // 获取算法参数
        CalculatorDTO carProuctDto = null;// 车款
        CalculatorDTO addProductDto = null;// 附加贷
        List<CalculatorDTO> costList = condition.getCostList();
        for(CalculatorDTO calculatorDto:costList){
            String costType = calculatorDto.getCostType();
            if(CostType.CARAMT.getIndex().equals(costType)){
                carProuctDto = calculatorDto;
            }else if(CostType.AFFIXAMT.getIndex().equals(costType)){
                addProductDto = calculatorDto;
            }
        }
        Assert.isTrue(carProuctDto != null,"车款融资信息不能为空");
        // 调用计算器
        List<CalculatorDTO> inList = financeCalculatorService.getProductParameter(productJson.getData(),carProuctDto,addProductDto);
        return this.financeCalculation(inList);
    }

}
